package controllers

import java.io.File

import dao._
import javax.inject.Inject
import models.Tables._
import org.apache.commons.io.FileUtils
import org.joda.time.DateTime
import play.api.libs.json.Json
import play.api.mvc.{AbstractController, ControllerComponents}
import tool.{FormTool, ReportTool, Tool}
import utils.Utils

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import implicits.Implicits._
import org.zeroturnaround.zip.ZipUtil
import shared.VarTool


/**
 * Created by Administrator on 2019/10/23
 */
class ConfigController @Inject()(cc: ControllerComponents, formTool: FormTool, configDao: ConfigDao,
                                 missionDao: MissionDao, userDao: UserDao)(implicit val modeDao: ModeDao) extends
  AbstractController(cc) {

  def nameCheck = Action.async { implicit request =>
    val data = FormTool.configNameForm.bindFromRequest.get
    val userId = Tool.getUserId
    configDao.selectByNameOp(userId, data.configName).map { opConfig =>
      opConfig match {
        case Some(y) => Ok(Json.obj("valid" -> false))
        case None =>
          val valid = true
          Ok(Json.obj("valid" -> valid))
      }
    }
  }

  def add = Action.async { implicit request =>
    val data = formTool.saveConfigForm.bindFromRequest().get
    val userId = Tool.getUserId
    missionDao.selectByMissionName(userId, data.missionName).flatMap { mission =>
      val missionId = mission.id
      val workspaceDir = Tool.getMissionWorkspaceDirById(missionId)
      val configFile = new File(workspaceDir, "config.txt")
      val row = ConfigRow(0, userId, data.configName, new DateTime())
      configDao.insertAndReturnId(row).map { id =>
        val configDir = Tool.getConfigDir
        val outConfigFile = new File(configDir, s"${id}.config")
        FileUtils.copyFile(configFile, outConfigFile)
        Ok(Json.toJson("success!"))
      }
    }
  }

  def addByFile = Action.async(parse.multipartFormData) { implicit request =>
    val data = FormTool.configNameForm.bindFromRequest().get
    val userId = Tool.getUserId
    val tmpDir = Tool.createTempDirectory("tmpDir")
    val configFile = Tool.fileMoveDir("file", tmpDir)
    val row = ConfigRow(0, userId, data.configName, new DateTime())
    configDao.insertAndReturnId(row).map { id =>
      val configDir = Tool.getConfigDir
      val outConfigFile = new File(configDir, s"${id}.config")
      FileUtils.copyFile(configFile, outConfigFile)
      Tool.deleteDirectory(tmpDir)
      Ok(Json.toJson("success!"))
    }
  }

  def getAllNames = Action.async { implicit request =>
    val userId = Tool.getUserId
    configDao.selectAll(userId).map {
      x =>
        val array = x.map { row =>
          Json.obj("text" -> row.name, "id" -> row.id)
        }
        Ok(Json.toJson(array))
    }
  }

  def getConfig = Action { implicit request =>
    val userId = Tool.getUserId
    val data = FormTool.idForm.bindFromRequest().get
    val configFile = Tool.getConfigFile(data.id)
    val map = configFile.csvLines.map { columns =>
      (columns(0) -> columns(1))
    }.toMap
    Ok(Json.toJson(map))
  }

  def downloadConfig = Action.async { implicit request =>
    val userId = Tool.getUserId
    val data = FormTool.idForm.bindFromRequest().get
    configDao.select(data.id).map { config =>
      val configFile = Tool.getConfigFile(data.id)
      val fileName = s"${config.name}.mcfg"
      Ok.sendFile(configFile).withHeaders(
        CONTENT_DISPOSITION -> Tool.getContentDisposition(s"${
          fileName
        }"),
        CONTENT_TYPE -> "application/x-download"
      )
    }
  }


  def manageBefore = Action.async { implicit request =>
    val userId = Tool.getUserId
    userDao.selectById(userId).map { x =>
      val isMet = false
      Ok(views.html.user.configManage(isMet))
    }

  }

  def getAll = Action.async {
    implicit request =>
      val userId = Tool.getUserId
      configDao.selectAll(userId).map {
        x =>
          val array = Utils.getArrayByTs(x)
          Ok(Json.toJson(array))
      }
  }

  def deleteById = Action.async { implicit request =>
    val data = FormTool.idForm.bindFromRequest().get
    configDao.deleteById(data.id).map { x =>
      Future {
        val configFile = Tool.getConfigFile(data.id)
        FileUtils.deleteQuietly(configFile)
      }
      Ok("success")
    }
  }

}
